import { createServerHandler } from "../core/handler.js";
import { logger } from "../core/logger.js";
import { Router } from "../core/router.js";
import { BaseEngine } from "./base.js";
import http from "node:http";
import { color, composeColors } from "robo.js";
export class NodeEngine extends BaseEngine {
    async init(options) {
        this._router = new Router();
        this._serverHandler = createServerHandler(this._router, options?.vite);
        this._server = http.createServer((req, res)=>this._serverHandler?.(req, res));
        this._server.on('error', (error)=>logger.error(`Server error:`, error));
        this._server.on('upgrade', (req, socket, head)=>{
            const handler = this._websocketHandlers[req.url ?? ''];
            if (handler) {
                handler(req, socket, head);
                return;
            }
            const defaultHandler = this._websocketHandlers['default'];
            if (defaultHandler) {
                defaultHandler(req, socket, head);
            } else {
                logger.warn(`No WebSocket handler found for`, req.url);
            }
        });
    }
    getHttpServer() {
        return this._server;
    }
    isRunning() {
        return this._isRunning;
    }
    registerRoute(path, handler) {
        this._router.addRoute({
            handler,
            path
        });
    }
    registerWebsocket(path, handler) {
        this._websocketHandlers[path] = handler;
    }
    setupVite(vite) {
        this._vite = vite;
        this._serverHandler = createServerHandler(this._router, vite);
    }
    async start(options) {
        const { hostname ='localhost' , port  } = options;
        return new Promise((resolve)=>{
            if (this._isRunning) {
                logger.warn('Server is already up and running. No action taken.');
                resolve();
                return;
            }
            // Start server
            this._isRunning = true;
            this._server.listen(port, hostname, ()=>{
                logger.ready(`Server is live at ${composeColors(color.bold, color.blue)(`http://${hostname}:${port}`)}`);
                resolve();
            });
        });
    }
    async stop() {
        const serverPromise = new Promise((resolve)=>{
            if (!this._server) {
                logger.debug(`Server isn't running. Nothing to stop here.`);
                resolve();
                return;
            }
            this._server.close((err)=>{
                if (err) {
                    logger.error(`Error stopping the server: ${err}`);
                    return;
                }
                this._isRunning = false;
                logger.debug('Server has been stopped successfully.');
                resolve();
            });
        });
        const vitePromise = this._vite?.close();
        await Promise.allSettled([
            serverPromise,
            vitePromise
        ]);
    }
    constructor(...args){
        super(...args);
        this._isRunning = false;
        this._router = null;
        this._server = null;
        this._vite = null;
        this._websocketHandlers = {};
        this._serverHandler = null;
    }
}
